﻿using System.Linq;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Abp.Authorization;
using Abp.Authorization.Roles;
using Abp.Authorization.Users;
using Abp.MultiTenancy;
using AbpProjectTemplate.Domain.Users.Admins;
using AbpProjectTemplate.Domain.Roles;

namespace AbpProjectTemplate.EntityFrameworkCore.Seed.Tenants
{
    public class TenantRoleAndUserBuilder
    {
        private readonly AppDbContext _context;
        private readonly int _tenantId;

        public TenantRoleAndUserBuilder(AppDbContext context, int tenantId)
        {
            this._context = context;
            this._tenantId = tenantId;
        }

        public void Create()
        {
            this.CreateRolesAndUsers();
        }

        private void CreateRolesAndUsers()
        {
            // Admin role

            var adminRole = this._context.Roles.IgnoreQueryFilters().FirstOrDefault(r => r.TenantId == this._tenantId && r.Name == AppRoleConfig.AdminRoleName);
            if (adminRole == null)
            {
                adminRole = AppRoleConfig.CreateAdminRole(this._tenantId);
                this._context.Add(adminRole);
                this._context.SaveChanges();
            }

            // Grant all permissions to admin role

            //var grantedPermissions = _context.Permissions.IgnoreQueryFilters()
            //    .OfType<RolePermissionSetting>()
            //    .Where(p => p.TenantId == _tenantId && p.RoleId == adminRole.Id)
            //    .Select(p => p.Name)
            //    .ToList();

            //var permissions = PermissionFinder
            //    .GetAllPermissions(new AppAuthorizationProvider())
            //    .Where(p => p.MultiTenancySides.HasFlag(MultiTenancySides.Tenant) &&
            //                !grantedPermissions.Contains(p.Name))
            //    .ToList();

            //if (permissions.Any())
            //{
            //    _context.Permissions.AddRange(
            //        permissions.Select(permission => new RolePermissionSetting
            //        {
            //            TenantId = _tenantId,
            //            Name = permission.Name,
            //            IsGranted = true,
            //            RoleId = adminRole.Id
            //        })
            //    );
            //    _context.SaveChanges();
            //}

            // Admin user

            var adminUser = this._context.Users.IgnoreQueryFilters().FirstOrDefault(u => u.TenantId == this._tenantId && u.UserName == AbpUserBase.AdminUserName);
            if (adminUser == null)
            {
                adminUser = Admin.CreateDefaultAdmin(this._tenantId);
                
                this._context.Users.Add(adminUser);
                this._context.SaveChanges();

                // Assign Admin role to admin user
                this._context.UserRoles.Add(new UserRole(this._tenantId, adminUser.Id, adminRole.Id));
                this._context.SaveChanges();
            }
        }
    }
}

